<?php

declare(strict_types=1);

namespace DreamCat\StateMachine\Popo;

use DreamCat\StateMachine\Popo\Define\MachineActionDetail;
use DreamCat\StateMachine\Popo\Define\MachineNodeDetail;
use DreamCat\StateMachine\Popo\Define\MachineRoleDetail;

/**
 * 状态机定义
 * @author vijay
 */
class MachineDefine
{
    /** @var string 状态机工厂类名 */
    private string $machineFactoryClass;
    /** @var MachineNodeDetail[] 节点列表，key是节点标识 */
    private array $nodeList = [];
    /** @var MachineActionDetail[] 动作列表，key是动作标识 */
    private array $actionList = [];
    /** @var MachineRoleDetail[] 角色列表，key是角色标识 */
    private array $roleList = [];

    /**
     * @return string 状态机工厂类名
     */
    public function getMachineFactoryClass(): string
    {
        return $this->machineFactoryClass;
    }

    /**
     * @param string $machineFactoryClass 状态机工厂类名
     */
    public function setMachineFactoryClass(string $machineFactoryClass): void
    {
        $this->machineFactoryClass = $machineFactoryClass;
    }

    /**
     * @return MachineNodeDetail[] 节点列表，key是节点标识
     */
    public function getNodeList(): array
    {
        return $this->nodeList;
    }

    /**
     * 通知节点名取节点信息
     * @param string $key
     * @return MachineNodeDetail|null
     */
    public function getNode(string $key): ?MachineNodeDetail
    {
        return $this->nodeList[$key] ?? null;
    }

    /**
     * 添加一个节点
     * @param MachineNodeDetail $node 节点详情
     * @return MachineNodeDetail|null 如果原本存在则返回旧的，否则返回null
     */
    public function addNode(MachineNodeDetail $node): ?MachineNodeDetail
    {
        $tmp = $this->nodeList[$node->getKey()] ?? null;
        $this->nodeList[$node->getKey()] = $node;
        return $tmp;
    }

    /**
     * 删除节点
     * @param string $nodeId 节点id
     * @return MachineNodeDetail|null 如果原本存在则返回旧的，否则返回null
     */
    public function deleteNode(string $nodeId): ?MachineNodeDetail
    {
        $tmp = $this->nodeList[$nodeId] ?? null;
        unset($this->nodeList[$nodeId]);
        return $tmp;
    }

    /**
     * 清除节点
     * @return MachineNodeDetail[] 旧的节点列表
     */
    public function clearNode(): array
    {
        $list = $this->nodeList;
        $this->nodeList = [];
        return $list;
    }

    /**
     * @return MachineActionDetail[] 动作列表，key是动作标识
     */
    public function getActionList(): array
    {
        return $this->actionList;
    }

    /**
     * 通知动作标识取动作信息
     * @param string $key 动作标识
     * @return MachineActionDetail|null
     */
    public function getAction(string $key): ?MachineActionDetail
    {
        return $this->actionList[$key] ?? null;
    }

    /**
     * 添加一个动作
     * @param MachineActionDetail $action 动作
     * @return MachineActionDetail|null 如果原本存在则返回旧的，否则返回null
     */
    public function addAction(MachineActionDetail $action): ?MachineActionDetail
    {
        $tmp = $this->actionList[$action->getKey()] ?? null;
        $this->actionList[$action->getKey()] = $action;
        return $tmp;
    }

    /**
     * 删除动作
     * @param string $actionId 动作id
     * @return MachineActionDetail|null 如果原本存在则返回旧的，否则返回null
     */
    public function deleteAction(string $actionId): ?MachineNodeDetail
    {
        $tmp = $this->actionList[$actionId] ?? null;
        unset($this->actionList[$actionId]);
        return $tmp;
    }

    /**
     * 清除动作
     * @return MachineActionDetail[] 旧的动作列表
     */
    public function clearAction(): array
    {
        $list = $this->actionList;
        $this->actionList = [];
        return $list;
    }

    /**
     * @return MachineRoleDetail[] 角色列表，key是角色标识
     */
    public function getRoleList(): array
    {
        return $this->roleList;
    }

    /**
     * 通知角色id标识取动作信息
     * @param string $roleId 角色id
     * @return MachineRoleDetail|null
     */
    public function getRole(string $roleId): ?MachineRoleDetail
    {
        return $this->roleList[$roleId] ?? null;
    }

    /**
     * @param MachineRoleDetail[] $roleList 角色列表
     * @return MachineDefine
     */
    public function setRoleList(array $roleList): MachineDefine
    {
        $this->roleList = [];
        foreach ($roleList as $role) {
            $this->addRole($role);
        }
        return $this;
    }

    /**
     * 添加一个角色
     * @param MachineRoleDetail $role 要添加的角色
     * @return MachineRoleDetail|null 如果原本存在则返回旧的，否则返回null
     */
    public function addRole(MachineRoleDetail $role): ?MachineRoleDetail
    {
        $tmp = $this->roleList[$role->getId()] ?? null;
        $this->roleList[$role->getId()] = $role;
        return $tmp;
    }

    /**
     * 删除角色
     * @param string $roleId 角色标识
     * @return MachineRoleDetail|null 如果原本存在则返回旧的，否则返回null
     */
    public function deleteRole(string $roleId): ?MachineRoleDetail
    {
        $tmp = $this->roleList[$roleId] ?? null;
        unset($this->roleList[$roleId]);
        return $tmp;
    }

    /**
     * 清除角色
     * @return MachineRoleDetail[] 旧的角色列表
     */
    public function clearRoleList(): array
    {
        $list = $this->roleList;
        $this->roleList = [];
        return $list;
    }
}

# end of file
